﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Xml.Serialization;
using ElectronicCommerce.Framework.ServiceModel.WCF.BindingMessage;

namespace ElectronicCommerce.Framework.ServiceModel.WCF.TransferElement
{
    public class NetNamedPipeBindingHandler : IGetBindingByConfig
    {
        #region IGetBindingByConfig Members

        public System.ServiceModel.Channels.Binding GetBindingMsgByConfig(string configStr)
        {
            if (string.IsNullOrEmpty(configStr))
                return new NetNamedPipeBinding();
            else
            {
                XmlSerializer serial = new XmlSerializer(typeof(NetNamedPipeBindingMsg));
                NetNamedPipeBindingMsg bindingMsg = (NetNamedPipeBindingMsg)serial.Deserialize(new StringReader(configStr));
                return GetBindingFromMsg(bindingMsg);
            }
        }

        #endregion

        private NetNamedPipeBinding GetBindingFromMsg(NetNamedPipeBindingMsg bindingMsg)
        {
            NetNamedPipeBinding binding = new NetNamedPipeBinding();
            if (bindingMsg.name != null)
            {
                binding.Name = bindingMsg.name;
            }


            if (bindingMsg.closeTimeout != null)
            {
                binding.CloseTimeout = TimeSpan.Parse(bindingMsg.closeTimeout);
            }

            binding.MaxBufferSize = bindingMsg.maxBufferSize;
            binding.MaxConnections = bindingMsg.maxConnections;

            binding.HostNameComparisonMode = (HostNameComparisonMode)bindingMsg.hostNameComparisonMode;
            binding.MaxBufferPoolSize = bindingMsg.maxBufferPoolSize;
            binding.MaxReceivedMessageSize = bindingMsg.maxReceivedMessageSize;

            if (bindingMsg.openTimeout != null)
            {
                binding.OpenTimeout = TimeSpan.Parse(bindingMsg.openTimeout);
            }
            if (bindingMsg.receiveTimeout != null)
            {
                binding.ReceiveTimeout = TimeSpan.Parse(bindingMsg.receiveTimeout);
            }
            if (bindingMsg.sendTimeout != null)
            {
                binding.SendTimeout = TimeSpan.Parse(bindingMsg.sendTimeout);
            }
            binding.TransactionFlow = bindingMsg.transactionFlow;
            binding.TransactionProtocol = GetTransactionProtocol(bindingMsg.transactionProtocol);
            binding.TransferMode = (TransferMode)bindingMsg.transferMode;

            if (bindingMsg.readerQuotas != null)
            {
                binding.ReaderQuotas.MaxArrayLength = bindingMsg.readerQuotas.maxArrayLength;
                binding.ReaderQuotas.MaxBytesPerRead = bindingMsg.readerQuotas.maxBytesPerRead;
                binding.ReaderQuotas.MaxDepth = bindingMsg.readerQuotas.maxDepth;
                binding.ReaderQuotas.MaxNameTableCharCount = bindingMsg.readerQuotas.maxNameTableCharCount;
                binding.ReaderQuotas.MaxStringContentLength = bindingMsg.readerQuotas.maxStringContentLength;
            }

            if (bindingMsg.security != null)
            {
                TranNetTcpSecurity(bindingMsg, binding);
            }

            return binding;
        }

        private TransactionProtocol GetTransactionProtocol(string transactionProtocol)
        {
            switch (transactionProtocol)
            {
                case "OleTransactions":
                    return TransactionProtocol.OleTransactions;

                //case "WSAtomicTransaction11":
                //    return TransactionProtocol.WSAtomicTransaction11;

                case "WSAtomicTransactionOctober2004":
                    return TransactionProtocol.WSAtomicTransactionOctober2004;

                default:
                    return TransactionProtocol.Default;
            }
        }

        private void TranNetTcpSecurity(NetNamedPipeBindingMsg bindingMsg, NetNamedPipeBinding binding)
        {
            switch (bindingMsg.security.mode)
            {
                case NetNamedPipeBindingMsgSecurityMode.None:
                    binding.Security.Mode = NetNamedPipeSecurityMode.None;
                    break;
                case NetNamedPipeBindingMsgSecurityMode.Transport:
                    binding.Security.Mode = NetNamedPipeSecurityMode.Transport;
                    binding.Security.Transport.ProtectionLevel = (System.Net.Security.ProtectionLevel)bindingMsg.security.transport.protectionLevel;
                    break;
                default:
                    binding.Security.Mode = NetNamedPipeSecurityMode.None;
                    break;
            }
        }



        #region IGetBindingByConfig Members


        public string GetAddress(string templateAddress)
        {
            return String.Format("net.pipe://{0}", templateAddress);
        }

        #endregion
    }
}
